﻿using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;

namespace DotNetExtensions.Core.WebApi.Jwt
{
    public abstract class JwtValidateService<T> : IJwtValidateService<T> where T : class, new()
    {
        public virtual bool Validate(string token, JwtParameters parameters, out T user, out string refreshKey)
        {
            user = null;
            refreshKey = string.Empty;
            return false;
        }

        public virtual string CreateJwtToken(JwtParameters parameters, int expiredMunutes, out string audience, out DateTime expiredTime)
        {
            audience = Guid.NewGuid().ToString();
            DateTime nbfTime = DateTime.UtcNow;
            long nbf = new DateTimeOffset(nbfTime).ToUnixTimeSeconds();
            expiredTime = nbfTime.AddMinutes(expiredMunutes);
            long exp = new DateTimeOffset(expiredTime).ToUnixTimeSeconds();
            List<Claim> claims = new List<Claim>();

            foreach (var item in parameters)
            {
                claims.Add(new Claim(item.Name, item.Value));
            }
            if (!parameters.Any(c => c.Name == JwtRegisteredClaimNames.Nbf))
                claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, $"{nbf}"));
            if (!parameters.Any(c => c.Name == JwtRegisteredClaimNames.Exp))
                claims.Add(new Claim(JwtRegisteredClaimNames.Exp, $"{exp}"));

            SymmetricSecurityKey key = new SymmetricSecurityKey(JwtOption.Default.SecurityKeyBuffer);
            SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(issuer: JwtOption.Default.Issuer, audience, signingCredentials: creds, claims: claims);
            return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
        }
    }
}
